<?php

namespace App\Library\Service;

use App\Library\Logic\AuctionBailLogic;
use App\Library\Logic\AuctionLogic;
use App\Library\Logic\AuctionOrderLogic;
use App\Library\Logic\PaymentRelatedLogic;
use App\Library\Requests\Pay\PayAuctionBailRequest;
use App\Library\Requests\Pay\PayAuctionRequest;
use App\Library\Service\Payment\WechatService;
use App\Library\YsdLib;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Yansongda\Artful\Exception\ContainerException;
use Yansongda\Artful\Exception\InvalidParamsException;
use Yansongda\Artful\Exception\ServiceNotFoundException;
use Yansongda\Artful\Rocket;
use Yansongda\Pay\Pay;
use Yansongda\Supports\Collection;

class PayService extends BaseService
{
    /**
     * @return ResponseInterface
     * @throws ContainerException
     * @throws InvalidParamsException
     * @throws ServiceNotFoundException
     */
    public static function notify(): ResponseInterface
    {file_put_contents('./notify2.txt','notify2');
        $result = Pay::wechat()->callback(request()->post());
        $query = WechatService::successTrait($result);
        if (is_null($query)) return Pay::wechat()->success();
        $serialNumber = $result->get('resource.ciphertext.out_trade_no');
        WechatService::paySuccess($serialNumber, $result, $query);
        return Pay::wechat()->success();
    }

    /**
     * 拉起支付
     * @param PayAuctionRequest $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function auctionOrder(PayAuctionRequest $request): JsonResponse
    {
        $order = AuctionOrderLogic::findBySerialNumber($request);
        if (is_null($order)) return fail(439);
        else if (!is_null($order->pay_at)) return failMessage('订单已经支付');
        else if (!is_null($order->cancel_at)) return failMessage('订单已经取消');
        else if (is_null($order->receive_info)) return failMessage('您还未添加收货地址');
        else if (now()->gte(now()->parse($order->pay_end_at))) return failMessage('付款时间已经截止');
        $data = handleRequest($request);
        $where = [
            'objectType' => humpToLine(__FUNCTION__),
            'objectId' => $order->id,
            'paymentMethodId' => $data['paymentMethodId'],
            'method' => $data['method'],
        ];
        $paymentRelated = PaymentRelatedLogic::add($where);
        return WechatService::mini($order, $paymentRelated->serial_number, $data['code'], 1);
    }

    /**
     * 拉起支付
     * @param PayAuctionBailRequest $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function auctionBail(PayAuctionBailRequest $request): JsonResponse
    {
        $auction = AuctionLogic::findBySerialNumber($request);
        if (is_null($auction)) return fail(439);
        else if ($auction->publish_id === USERID) return failMessage('不能参与自己发布的');
        else if ($auction->bail_price * 1 === 0) return failMessage('当前拍品无需缴纳保证金');
        $item = AuctionBailLogic::myBailOfAuctionId($auction->id);
        if (is_null($item)) $item = AuctionBailLogic::add($auction);
        else if ($item->status_pay === 1) return failMessage('当前已经缴纳过保证金了');
        $data = handleRequest($request);
        $where = [
            'objectId' => $item->id,
            'objectType' => humpToLine(__FUNCTION__),
            'paymentMethodId' => $data['paymentMethodId'],
            'method' => $data['method'],
        ];
        $paymentRelated = PaymentRelatedLogic::add($where);
        return WechatService::mini($item, $paymentRelated->serial_number, $data['code'], 1);
    }

    /**
     * @param Collection|Rocket $result
     * @return ResponseInterface
     * @throws ContainerException|InvalidParamsException|ServiceNotFoundException|InvalidParamsException
     */
    public static function wechatNotify(Collection|Rocket $result): ResponseInterface
    {file_put_contents('./wechatNotify.txt','wechatNotify');
        $query = WechatService::successTrait($result);
        if (is_null($query)) return Pay::wechat()->success();
        $serialNumber = $result->get('resource.ciphertext.out_trade_no');
        WechatService::paySuccess($serialNumber, $result, $query);
        return Pay::wechat()->success();
    }
}
